package com.bto.solar.work.fdd;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.bto.solar.work.common.BizException;
import com.bto.solar.work.constant.Constants;
import com.bto.solar.work.constant.SignTaskStatusEnum;
import com.bto.solar.work.dao.ICustomerService;
import com.bto.solar.work.dao.IFddTaskService;
import com.bto.solar.work.dao.IOrderBaseService;
import com.bto.solar.work.entity.Customer;
import com.bto.solar.work.entity.FddTask;
import com.bto.solar.work.entity.OrderBase;
import com.bto.solar.work.fdd.client.FddBaseClient;
import com.bto.solar.work.fdd.client.FddSignTaskClient;
import com.bto.solar.work.fdd.client.FddTemplateClient;
import com.bto.solar.work.utils.StringUtils;
import com.fasc.open.api.bean.base.BaseRes;
import com.fasc.open.api.exception.ApiException;
import com.fasc.open.api.utils.ResultUtil;
import com.fasc.open.api.v5_1.client.OrgClient;
import com.fasc.open.api.v5_1.client.SignTaskClient;
import com.fasc.open.api.v5_1.req.org.GetMemberListFilter;
import com.fasc.open.api.v5_1.req.org.GetMemberListReq;
import com.fasc.open.api.v5_1.req.signtask.*;
import com.fasc.open.api.v5_1.res.org.GetMemberListRes;
import com.fasc.open.api.v5_1.res.signtask.*;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * @author 王小波
 * @description: 法大大相关的接口
 * @date 2023/7/17 15:05
 */

@Slf4j
@Service
public class FddService {

    @Value("${fdd.open-crop-id}")
    private String openCorpId;

    @Autowired
    @Lazy
    private FddBaseClient fddBaseClient;
    @Autowired
    private FddTemplateClient fddTemplateClient;
    @Autowired
    private FddSignTaskClient fddSignTaskClient;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IOrderBaseService orderService;
    @Autowired
    private IFddTaskService fddTaskService;

    /**
     * 获取 签署方专属连接
     * 是包含创建签署任务的，任务的有效期只有30分钟。业务每次进行签署动作都是重新创建任务，获取签署链接
     */
    public SignTaskActorGetUrlRes getActorUrl(String orderId, String signType , String stageId , String taskId) {
        OrderBase orderBase = orderService.getById(orderId);
        if (null == orderBase) {
            throw new BizException("订单不存在 id：{}", orderId);
        }
        Customer customer = customerService.getById(orderBase.getCustomerId());
        if (StringUtils.isAnyBlank(orderBase.getName(), customer.getPhone())) {
            throw new BizException("订单客户名成 name {}  手机号码 {} 无效", orderBase.getName(), customer.getPhone());
        }

        // 判断是否再次创建签署任务
        //fddSignTaskClient.isCreateSignTask(orderId);

        //创建 参与方的个人信息，签署任务信息的请求体
        CreateSignTaskReq personalInfoUsedReq = fddSignTaskClient.createSignTaskPersonalInfoUsedReq(orderBase, signType);
        try {
            SignTaskClient signTaskClient = fddSignTaskClient.getFddSignTaskClient();
            //创建签署任务
            BaseRes<CreateSignTaskRes> signTaskResBaseRes = signTaskClient.create(personalInfoUsedReq);
            if (!Constants.FDD_OK.equals(signTaskResBaseRes.getCode())) {
                throw new BizException("法大大创建签约任务失败 订单id {}  错误信息 {}", orderBase.getOrderId(), signTaskResBaseRes.getMsg());
            }
            String signTaskId = signTaskResBaseRes.getData().getSignTaskId();
            //添加创建记录
            recordSignTaskCreatedSuccess(orderBase, stageId , taskId , signType, signTaskId);
            //获取签署任务id
            log.info("创建个人信息授权签署任务成功 订单id  {}" , orderBase.getOrderId());
            //获取签署任务专属连接
            BaseRes<SignTaskActorGetUrlRes> actorGetUrlRes = signTaskClient.signTaskActorGetUrl(fddSignTaskClient.createSignTaskActorGetUrlReq(orderBase, signTaskId));
            if (!Constants.FDD_OK.equals(actorGetUrlRes.getCode())) {
                throw new BizException("法大大获取签署专属连接失败 订单id {} }  错误信息 {}", orderBase.getOrderId(), actorGetUrlRes.getMsg());
            }
            log.info("获取签署任务参与方专属链接成功 {}" , JSON.toJSONString(actorGetUrlRes));
            //记录签署方式
            orderBase.setSigningType(signType);
            orderService.updateById(orderBase);

            return actorGetUrlRes.getData();
        } catch (ApiException e) {
            throw new BizException("法大大个人信息授权，签署任务创建失败 {}", e.getMessage());
        }
    }

    /**
     * 作废签署任务
     */
    public String abolishSignTask(String orderId, String reason) {
        OrderBase orderBase = orderService.getById(orderId);
        if (null == orderBase) {
            throw new BizException("订单不存在 id：{}", orderId);
        }
        //获取签署任务id
        FddTask fddTask = getSignTaskIdByOrderId(orderId);
        if (null == fddTask) {
            throw new BizException("未找到签署任务id，无法作废 订单id {}", orderId);
        }
        BaseRes<CancelSignTaskCreateRes> res = fddSignTaskClient.abolishSignTask(orderBase, fddTask.getSignTaskId(), reason);
        String abolishedSignTaskId = res.getData().getAbolishedSignTaskId();

        FddTask signTaskIdByOrderId = getSignTaskIdByOrderId(orderId);
        if (null == signTaskIdByOrderId) {
            throw new BizException("订单 id：{}， 签署任务不存在", orderId);
        }
        signTaskIdByOrderId.setAbolishSignTaskId(abolishedSignTaskId);
        fddTaskService.updateById(signTaskIdByOrderId);
        return abolishedSignTaskId;
    }


    /**
     * 获取签署任务的详情
     */
    public SignTaskDetailRes getSignTaskDetail(String orderId) {
        OrderBase orderBase = orderService.getById(orderId);
        if (null == orderBase) {
            throw new BizException("订单不存在 id：{}", orderId);
        }
        Customer customer = customerService.getById(orderBase.getCustomerId());
        if (null == customer) {
            throw new BizException("客户不存在 id：{}", orderBase.getCustomerId());
        }
        FddTask fddTask = getSignTaskIdByOrderId(orderId);
        if (null == fddTask) {
            throw new BizException("订单 id：{}， 签署任务不存在", orderId);
        }
        //再通过签署任务ID进行签署任务详情查询--查询状态
        SignTaskDetailRes signTaskDetailRes = fddSignTaskClient.getAppDetail(fddTask.getSignTaskId());
        //如果法大大的接口的任务状态与数据库任务状态不一致就更新
        if (!fddTask.getSignTaskStatus().equals(signTaskDetailRes.getSignTaskStatus())) {
            updateSignTaskCreated(orderId, fddTask.getSignTaskId(), signTaskDetailRes.getSignTaskStatus());
        }
        return signTaskDetailRes;
    }

    /**
     * 获取签署任务预览链接
     */
    public String getSignTaskPreviewUrl(String orderId) {
        FddTask fddTask = getSignTaskIdByOrderId(orderId);
        if (null == fddTask) {
            throw new BizException("订单 id：{}， 签署任务不存在", orderId);
        }
        return fddSignTaskClient.getSignTaskPreviewUrl(fddTask.getSignTaskId());
    }

    /**
     * 催办签署任务
     */
    public boolean signTaskUrge(String orderId) {
        FddTask fddTask = getSignTaskIdByOrderId(orderId);
        if (null == fddTask) {
            throw new BizException("订单 id：{}，签署任务不存在", orderId);
        }
        return Constants.FDD_OK.equals(fddSignTaskClient.signTaskUrge(fddTask.getSignTaskId()));
    }

    /**
     * 获取签署文档切图
     */
    public String getSignTaskOwnerSlicingTicketId(String orderId) {
        FddTask fddTask = getSignTaskIdByOrderId(orderId);
        if (null == fddTask) {
            throw new BizException("订单 id：{}，签署任务不存在", orderId);
        }
        return fddSignTaskClient.getSignTaskOwnerSlicingTicketId(fddTask.getSignTaskId());
    }

    /**
     * 获取图片版签署文档下载地址
     */
    public String getSignTaskOwnerPicDownloadUrl(String slicingTicketId) {
        if (null == slicingTicketId) {
            throw new BizException("slicingTicketId不能为空");
        }
        return fddSignTaskClient.getSignTaskOwnerPicDownloadUrl(slicingTicketId);
    }

    /**
     * 获取签署文档下载地址
     */
    public String getOwnerDownloadUrl(String orderId) {
        FddTask fddTask = getSignTaskIdByOrderId(orderId);
        if (null == fddTask) {
            return null;
        }
        return fddSignTaskClient.getOwnerDownloadUrl(fddTask.getSignTaskId()).getDownloadUrl();
    }

    /**
     * 查询签署任务列表
     */
    public GetSignTaskListRes getOwnerList(String signTaskSubject, List<String> signTaskStatusList,
                                           int pageNo, int pageSize) {
        return fddSignTaskClient.getOwnerList(signTaskSubject, signTaskStatusList, pageNo, pageSize);
    }


    /**
     * 获取公司成员 -- 如果有多个公司成员的话，签约的InitiatorMemberId需要这里获取
     */
    public  void getCorpMemberList() throws ApiException {
        OrgClient orgClient = new OrgClient(fddBaseClient.getFddOpenApiClient());
        GetMemberListReq req = new GetMemberListReq();
        req.setAccessToken(fddBaseClient.getFddAccessToken());
        //法大大平台为该企业在该应用appId范围内分配的唯一标识。
        req.setOwnerId(openCorpId);
        //（可选）查询条件
        GetMemberListFilter filter = new GetMemberListFilter();
        //部门Id
        filter.setDeptId(null);
        //如果为true，则同时获取其所有子部门员工; 如果为false或者不传，则只获取当前部门员工,默认为true
        filter.setFetchChild(true);
        //角色类型，如传该字段，表示查询该角色的成员,目前只支持super_admin：超级管理员；如不传，表示查询所有成员
        filter.setRoleType("super_admin");
        req.setListFilter(filter);
        //（可选）查询结果分页返回，此处指定第几页，如果不传默从第一页返回。页码从1开始，即首页为1
        req.setListPageNo(1);
        //（可选）指定每页多少条数据，如果不传默认为100，单页最大100
        req.setListPageSize(100);
        BaseRes<GetMemberListRes> res = orgClient.getMemberList(req);
        ResultUtil.printLog(res, fddBaseClient.getFddOpenApiClient().getJsonStrategy());
    }


    /**
    *  保存成功创建法大大签约的记录
    */
    private void recordSignTaskCreatedSuccess(OrderBase orderBase, String stageId , String taskId , String signType, String  fddSignTaskId) {
        FddTask fddTask = new FddTask();
        fddTask.setOrderId(orderBase.getOrderId());
        fddTask.setStageId(stageId);
        fddTask.setStateId(null);
        fddTask.setSignType(signType);
        fddTask.setSignTaskId(fddSignTaskId);
        //填写中，因为是自动提交任务并且有必填项
        fddTask.setSignTaskStatus(SignTaskStatusEnum.FILL_PROGRESS.getStatus());
        fddTaskService.save(fddTask);
    }

    /**
     *  更新法大大签约的记录
     */
    private void updateSignTaskCreated(String orderId, String  fddSignTaskId, String signTaskStatus) {
        LambdaUpdateWrapper<FddTask> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FddTask::getSignTaskId, fddSignTaskId).eq(FddTask::getOrderId, orderId)
                .set(FddTask::getSignTaskStatus, signTaskStatus);
        fddTaskService.update(null, updateWrapper);
    }

    /**
     *  更新法大大作废的记录
     */
    private void updateSignTaskAbolish(String orderId, String  fddSignTaskId, String signTaskStatus, String abolishSignTaskId) {
        LambdaUpdateWrapper<FddTask> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(FddTask::getSignTaskId, fddSignTaskId).eq(FddTask::getOrderId, orderId)
                .set(FddTask::getAbolishSignTaskId, abolishSignTaskId)
                .set(FddTask::getSignTaskStatus, signTaskStatus);
        fddTaskService.update(null, updateWrapper);
    }


    /**
     *  通过orderId查询最新的签署任务ID
     */
    public FddTask getSignTaskIdByOrderId(String orderId) {
        //先通过数据库查询该订单是否已经创建签署任务--查询最新的记录
        OrderBase orderBase = orderService.getById(orderId);
        return fddTaskService.lambdaQuery()
                .eq(FddTask::getSignTaskId, orderBase.getFddSignTaskId()).one();
    }


}
